/*
 * Copyright 2008 Max Kugland
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.splink.library.logging {
	import flash.events.TimerEvent;	import flash.utils.Dictionary;	import flash.utils.Timer;
	import org.splink.library.distributor.Distributor;	

	/**
	 * <code>GarbageWatchDog</code> watches a given object until it gets garbage collected.
	 * Because <code>GarbageWatchDog</code> holds the reference to the given object within a
	 * <code>Dictionary</code> with weak keys enabled, <code>GarbageWatchDog</code> does not prevent
	 * the monitored object to get garbage collected.
	 * 
	 * Idea found at http://www.danielhai.com/blog/?p=49
	 * 
	 * @author Max Kugland
	 */
	public class GarbageWatchDog extends Distributor {
		private var _dictionary : Dictionary = new Dictionary(true);
		private var _timer : Timer = new Timer(500);
		private var _id : String;

		public function GarbageWatchDog(obj : *, id : String) {
			if(_dictionary[obj] == 1) return;
			_dictionary[obj] = 1;
			_id = id;

			_timer.addEventListener(TimerEvent.TIMER, run);
			_timer.start();
		}

		public function run(e : TimerEvent) : void {
			for (var obj:Object in _dictionary) { 
				obj = obj; // to prevent "unused var warning in fdt 
				return; 
			}
			
			_timer.removeEventListener(TimerEvent.TIMER, run);
			_timer.stop();
			_timer = null;
			
			distribute(new GarbageWatchDogEvent(this, GarbageWatchDogEvent.COLLECTED, _id));
			super.finalize();
		}
	}
}
